Flutter VirtualDisplayController
在 Virtual displays 模式中,Android 侧最底层是基于 Android 的 VirtualDisplay 机制实现的。而 VirtualDisplayController 这个 Java 类,就是对 Android VirtualDisplay 机制的封装。因此,研究这个类,就能够了解 Virtual displays 模式在 Android 侧的核心原理。
类属性
// Android Context
private final Context context;
// 处理和分派无障碍事件
private final AccessibilityEventsDelegate accessibilityEventsDelegate;
// 设备的屏幕密度
private final int densityDpi;
private final TextureRegistry.SurfaceTextureEntry textureEntry;
// 监听焦点变化事件
private final OnFocusChangeListener focusChangeListener;
private VirtualDisplay virtualDisplay;
// Android Presentation
@VisibleForTesting SingleViewPresentation presentation;
// Android Surface
private final Surface surface;
其中,比较关键的几个:
- VirtualDisplay:Android 的虚拟显示器
- TextureRegistry.SurfaceTextureEntry:接口,表示 TextureRegistry 中的条目,该接口内 3 个方法:
surfaceTexture
、id
、release
- SingleViewPresentation:基于 Android Presentation,使用 VirtualDisplay,原生视图向 Presentation 中添加“展示”
- Surface:Android SurfaceTexture 中,用于接受输入的图像流。
VirtualDisplayController 的创建
create 方法
VirtualDisplayController 专门有一个静态 create
方法,用于创建 VirtualDisplayController 实例:
public static VirtualDisplayController create(
Context context,
AccessibilityEventsDelegate accessibilityEventsDelegate,
PlatformViewFactory viewFactory,
TextureRegistry.SurfaceTextureEntry textureEntry,
int width, int height, int viewId,
Object createParams,
OnFocusChangeListener focusChangeListener) {
// 设置缓冲区大小
textureEntry.surfaceTexture().setDefaultBufferSize(width, height);
// 创建 Surface,关联 surfaceTexture
Surface surface = new Surface(textureEntry.surfaceTexture());
// 创建 VirtualDisplay
DisplayManager displayManager =
(DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
int densityDpi = context.getResources().getDisplayMetrics().densityDpi;
VirtualDisplay virtualDisplay =
displayManager.createVirtualDisplay("flutter-vd", width, height, densityDpi, surface, 0);
//...
return new VirtualDisplayController(
context,
accessibilityEventsDelegate,
virtualDisplay,
viewFactory,
surface,
textureEntry,
focusChangeListener,
viewId,
createParams);
}
其中:
SurfaceTextureEntry
是由外界传入的(内含 Android SurfaceTexture)- 创建了 Surface 与 Android SurfaceTexture 关联
- 创建 VirtualDisplay,虚拟显示器
构造方法
有了这些准备之后,接下来进入 VirtualDisplayController 构造函数:
private VirtualDisplayController(
Context context,
AccessibilityEventsDelegate accessibilityEventsDelegate,
VirtualDisplay virtualDisplay,
PlatformViewFactory viewFactory,
Surface surface,
TextureRegistry.SurfaceTextureEntry textureEntry,
OnFocusChangeListener focusChangeListener,
int viewId,
Object createParams) {
// 这些东东照单全收
this.context = context;
this.accessibilityEventsDelegate = accessibilityEventsDelegate;
this.textureEntry = textureEntry;
this.focusChangeListener = focusChangeListener;
this.surface = surface;
this.virtualDisplay = virtualDisplay;
densityDpi = context.getResources().getDisplayMetrics().densityDpi;
// 创建 Presentation
presentation =
new SingleViewPresentation(
context,
this.virtualDisplay.getDisplay(),
viewFactory,
accessibilityEventsDelegate,
viewId,
createParams,
focusChangeListener);
presentation.show();
}
其中,最为关键的是 SingleViewPresentation 的创建(具体可参见 《Flutter SingleViewPresentation》 ),可以看到,原生视图的创建工厂 viewFactory、VirtualDisplay、createParams,都传入其中,原生视图是在 SingleViewPresentation 中创建的无疑了。
最后一行,presentation.show()
触发 SingleViewPresentation 界面展示,并在 SingleViewPresentation 的生命周期内,创建原生视图。
谁调用 create
Flutter PlatformViewsController 是 Flutter 在 Android 侧处理 PlatformView 的统一处理者,不论是 Virtual displays 模式还是 Hybrid composition 模式,底层都由 PlatformViewsController 统一处理。
在 Flutter PlatformViewsController 中,当需要创建 Virtual displays 嵌入视图时,会在回调(createVirtualDisplayForPlatformView)中,创建本文的 VirtualDisplayController,作为视图维度、Virtual displays 模式绘制的处理者。
关于 createVirtualDisplayForPlatformView 回调,还可以参见可参见《Flutter PlatformViewsChannel#PlatformViewsHandler 接口》。
本文作者:Maeiee
本文链接:Flutter VirtualDisplayController
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!